package com.ccteam.fluidmusic.fluidmusic.common.utils

import android.content.Context
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaMetadataCompat
import com.ccteam.fluidmusic.fluidmusic.common.model.CurrentPlayingModel
import com.ccteam.fluidmusic.fluidmusic.common.repositories.impl.ProtoDataStoreRepository
import com.ccteam.fluidmusic.fluidmusic.media.extensions.*
import com.ccteam.fluidmusic.fluidmusic.room.AppDatabase
import com.ccteam.fluidmusic.fluidmusic.room.entity.MusicEntity
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton

/**
 * @author Xiaoc
 * @since 2020.1.22
 *
 * 播放列表相关存储工具功能
 * 主要负责将播放列表和当前播放项存储在Room和DataStore中
 *
 * 该类为单例，使用 Hilt 进行管理
 * */
@Singleton
class PlaylistStorage @Inject constructor(
    @ApplicationContext private val context: Context,
    private val protoDataStoreRepository: ProtoDataStoreRepository
) {
    /**
     * 存储当前正在播放的音乐内容
     * 通过 queueId 索引Id 和 position 播放位置进行存储
     * @param queueId 本质就是播放器当前播放的位置索引
     * @param position 播放器播放到该歌曲的具体位置 (ms)
     */
    suspend fun saveCurrentModel(queueId: Int,position: Long,repeatMode: Int,shuffleMode: Boolean){
        protoDataStoreRepository.saveCurrentPlaying(
            CurrentPlayingModel(queueId.toLong(),position,repeatMode,shuffleMode)
        )
    }

    /**
     * 加载当前音乐的QueueId索引Id
     */
    suspend fun loadCurrentPlayingModel(): CurrentPlayingModel{
        return protoDataStoreRepository.readCurrentPlaying().first()
    }

    /**
     * 从Room数据库中得到播放列表
     */
    suspend fun getPlaylist(): List<MediaMetadataCompat>{
        return withContext(Dispatchers.IO){
            val allMusic: List<MusicEntity> = AppDatabase.getDatabase(context).musicDao().getAllMusic()
            allMusic.map { music ->
                MediaMetadataCompat.Builder().apply {
                    id = music.mediaId
                    title = music.title
                    displayTitle = music.title
                    album = music.album
                    displayDescription = music.album
                    artist = music.artist
                    displaySubtitle = music.artist
                    duration = music.duration
                    mediaUri = music.mediaUri
                    albumArtUri = music.albumArtUri
                    displayIconUri = music.albumArtUri
                    albumId = music.albumId
                    artistId = music.artistId
                    flag = MediaBrowserCompat.MediaItem.FLAG_PLAYABLE
                    trackNumber = music.trackNum
                    year = music.year
                }.build()
            }
        }

    }


    /**
     * 保存播放列表到Room数据库
     */
    @Synchronized
    suspend fun savePlaylist(metadataList: List<MediaMetadataCompat>){
        withContext(Dispatchers.IO){

            val musicEntityList = metadataList.mapIndexed { index,metadata ->
                metadata.toMusicEntity(index.toLong())
            }
            // 删除数据库中的所有播放列表内容，并添加新的播放列表
            AppDatabase.getDatabase(context).musicDao().deleteAllAndInsertInTransaction(musicEntityList)
        }
    }
}